#include "NPC.h"
#include <QRandomGenerator>

NPC::NPC(MapManager *mapManager, QObject *parent)
    : Character(parent), m_mapManager(mapManager)
{
    setSpeed(80.0f);
}

void NPC::update(float deltaTime)
{
    Character::update(deltaTime); // 更新动画

    // 根据NPC类型选择对应的更新方式
    switch(m_npcStatus)
    {
    case BehaviorType::Wandering:
        updateWandering(deltaTime);
        break;
    case BehaviorType::StaticNpc:
        break;
    }

}

bool NPC::isPokemonBattle() {
    for (auto p : std::as_const(npcPokemon)) {
        if (p->isAlive())
            return true;
    }
    return false;
}

void NPC::initializeCollisionShape()
{
    setCollisionShapeMode(
        QGraphicsPixmapItem::HeuristicMaskShape); // 启发式近似（动态采样）
}

void NPC::updateWandering(float deltaTime)
{
    m_directionTimer += deltaTime;

    // 定期改变方向
    if (m_directionTimer >= DIRECTION_CHANGE_INTERVAL) {
        m_directionTimer = 0.0f;
        m_npcDirection = static_cast<Direction>(
            QRandomGenerator::global()->bounded(4));
    }

    // 计算移动距离
    float distance = m_speed * deltaTime;
    QPointF movement(0, 0);

    // 根据当前方向计算移动向量
    switch (m_npcDirection) {
    case DIR_LEFT:
        movement = QPointF(-distance, 0);
        break;
    case DIR_RIGHT:
        movement = QPointF(distance, 0);
        break;
    case DIR_UP:
        movement = QPointF(0, -distance);
        break;
    case DIR_DOWN:
        movement = QPointF(0, distance);
        break;
    }

    // 1.检查移动后是否在区域内
    QPointF newPos = pos() + movement;
    if (m_movementArea.isValid() && !m_movementArea.contains(newPos)) {
        // 如果新位置不在区域内，则改变方向
        m_npcDirection = static_cast<Direction>(
            QRandomGenerator::global()->bounded(4));
        return; // 跳过本次移动
    }

    // 2. 地形碰撞检测（障碍物、水域等）

    // if (checkTerrainCollision(newPos)) {
    //     // 尝试寻找安全位置
    //     QPointF safePos = findSafePosition(newPos);

    //     if (safePos != pos()) {
    //         // 直接移动到安全位置
    //         setPos(safePos);
    //     } else {
    //         // 找不到安全位置则改变方向
    //         m_currentDirection = static_cast<Character::Direction>(
    //             (m_currentDirection + 2 + QRandomGenerator::global()->bounded(2)) % 4);
    //     }
    //     return;
    // }

    if (checkTerrainCollision(newPos)) {
        return;
    }

    // 执行移动并更新方向
    move(movement.x(), movement.y());
    setCurrentDirection(m_npcDirection, false);
}

bool NPC::checkTerrainCollision(const QPointF& newPos) const
{
    if (!m_mapManager) return false;

    // 计算玩家所在的网格坐标
    const int tileSize = MapManager::tileSize;
    int tileX = static_cast<int>(newPos.x() + boundingRect().width()/2) / tileSize;
    int tileY = static_cast<int>(newPos.y() + boundingRect().height()/2) / tileSize;

    // 获取当前地图数据
    const MapData &map = m_mapManager->getCurrentMapData();

    // 检查边界
    if (tileX < 0 || tileX >= map.width || tileY < 0 || tileY >= map.height) {
        return true;
    }

    // 检查地形是否可通行
    int tileType = map.tileData[tileY][tileX];
    return (tileType == TerrainType::WALL || tileType == TerrainType::WATER);
}

QPointF NPC::findSafePosition(const QPointF& desiredPos) const
{
    if (!m_mapManager) return pos();

    const int tileSize = MapManager::tileSize;
    const int maxAttempts = 8; // 最大尝试次数

    // 尝试当前位置周围的8个方向
    QPointF directions[] = {
        QPointF(0, -tileSize),   // 上
        QPointF(tileSize, 0),    // 右
        QPointF(0, tileSize),    // 下
        QPointF(-tileSize, 0),   // 左
        QPointF(tileSize, -tileSize),  // 右上
        QPointF(tileSize, tileSize),   // 右下
        QPointF(-tileSize, tileSize),  // 左下
        QPointF(-tileSize, -tileSize)  // 左上
    };

    // 随机尝试顺序
    QVector<int> indices = {0, 1, 2, 3, 4, 5, 6, 7};
    std::shuffle(indices.begin(), indices.end(), *QRandomGenerator::global());

    for (int i = 0; i < maxAttempts; i++) {
        QPointF testPos = desiredPos + directions[indices[i]];

        // 检查是否在移动区域内
        if (m_movementArea.isValid() && !m_movementArea.contains(testPos)) {
            continue;
        }

        // 检查地形是否安全
        if (!checkTerrainCollision(testPos)) {
            return testPos;
        }
    }

    // 找不到安全位置则返回当前位置
    return pos();
}
